#include <sstream>
#include <string>
#include <stdexcept>
#include "Options/Options.hpp"

Options &Options::GetInstance() {
  static Options singleton;

  return (singleton);
}

Options::Options() {
  mCookingTime = 1;
  mCookingTime = 6;
  mStocksRefillTime = 0;
}

Options::~Options(void) {

}

std::string Options::GetUsage() const {
  std::ostringstream oss;

  oss << "Usage: ./plazza "
      << "<cooking time multiplier> <coocks per kitchen> <stocks refill time>";
  return (oss.str());
}

void Options::ParseParameters(int argc, char *argv[]) {
  if (argc == 4) {
    mCookingTime = GetDoubleFromString(argv[1]);
    mCooksPerKitchen = GetIntegerFromString(argv[2]);
    mStocksRefillTime = GetIntegerFromString(argv[3]);
    if (mCooksPerKitchen < 1)
      throw std::invalid_argument("We need at least one cooks per kitchen");
  }
  else
    throw std::invalid_argument(GetUsage());
}

double Options::GetCookingTime() const {
  return mCookingTime;
}

unsigned int Options::GetCooksPerKitchen() const {
  return mCooksPerKitchen;
}

unsigned int Options::GetStocksRefillTime() const {
  return mStocksRefillTime;
}

int Options::GetIntegerFromString(const std::string &string) const {
  std::istringstream iss(string);
  int value;

  if (!(iss >> value))
    throw std::invalid_argument("`" + string + "': Not an integer");
  if (value < 0)
    throw std::invalid_argument("`" + string + "': Expected a positive value");
  return value;
}

double Options::GetDoubleFromString(const std::string &string) const {
  std::istringstream iss(string);
  double value;

  if (!(iss >> value))
    throw std::invalid_argument(
	"`" + string + "': Not a valid floating number");
  if (value < 0)
    throw std::invalid_argument("`" + string + "': Expected a positive value");
  return value;
}
